
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>django.utils.http &#8212; Django 1.11.22.dev20190603194737 documentation</title>
    <link rel="stylesheet" href="../../../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
    <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../../_static/doctools.js"></script>
    <script type="text/javascript" src="../../../_static/language_data.js"></script>
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" />



 
<script type="text/javascript" src="../../../templatebuiltins.js"></script>
<script type="text/javascript">
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "../../../ref/templates/builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);
</script>


  </head><body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../../../index.html">Django 1.11.22.dev20190603194737 documentation</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../../../index.html">Home</a>  |
        <a title="Table of contents" href="../../../contents.html">Table of contents</a>  |
        <a title="Global index" href="../../../genindex.html">Index</a>  |
        <a title="Module index" href="../../../py-modindex.html">Modules</a>
      </div>
      <div class="nav">
    <a href="../../index.html" title="Module code" accesskey="U">up</a></div>
    </div>

    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="_modules-django-utils-http">
            
  <h1>Source code for django.utils.http</h1><div class="highlight"><pre>
<span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">unicode_literals</span>

<span class="kn">import</span> <span class="nn">base64</span>
<span class="kn">import</span> <span class="nn">calendar</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">unicodedata</span>
<span class="kn">import</span> <span class="nn">warnings</span>
<span class="kn">from</span> <span class="nn">binascii</span> <span class="k">import</span> <span class="n">Error</span> <span class="k">as</span> <span class="n">BinasciiError</span>
<span class="kn">from</span> <span class="nn">email.utils</span> <span class="k">import</span> <span class="n">formatdate</span>

<span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="k">import</span> <span class="n">TooManyFieldsSent</span>
<span class="kn">from</span> <span class="nn">django.utils</span> <span class="k">import</span> <span class="n">six</span>
<span class="kn">from</span> <span class="nn">django.utils.datastructures</span> <span class="k">import</span> <span class="n">MultiValueDict</span>
<span class="kn">from</span> <span class="nn">django.utils.deprecation</span> <span class="k">import</span> <span class="n">RemovedInDjango21Warning</span>
<span class="kn">from</span> <span class="nn">django.utils.encoding</span> <span class="k">import</span> <span class="n">force_bytes</span><span class="p">,</span> <span class="n">force_str</span><span class="p">,</span> <span class="n">force_text</span>
<span class="kn">from</span> <span class="nn">django.utils.functional</span> <span class="k">import</span> <span class="n">keep_lazy_text</span>
<span class="kn">from</span> <span class="nn">django.utils.six.moves.urllib.parse</span> <span class="k">import</span> <span class="p">(</span>
    <span class="n">quote</span><span class="p">,</span> <span class="n">quote_plus</span><span class="p">,</span> <span class="n">unquote</span><span class="p">,</span> <span class="n">unquote_plus</span><span class="p">,</span> <span class="n">urlencode</span> <span class="k">as</span> <span class="n">original_urlencode</span><span class="p">,</span>
<span class="p">)</span>

<span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY2</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">urlparse</span> <span class="k">import</span> <span class="p">(</span>
        <span class="n">ParseResult</span><span class="p">,</span> <span class="n">SplitResult</span><span class="p">,</span> <span class="n">_splitnetloc</span><span class="p">,</span> <span class="n">_splitparams</span><span class="p">,</span> <span class="n">scheme_chars</span><span class="p">,</span>
        <span class="n">uses_params</span><span class="p">,</span>
    <span class="p">)</span>
    <span class="n">_coerce_args</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">else</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">urllib.parse</span> <span class="k">import</span> <span class="p">(</span>
        <span class="n">ParseResult</span><span class="p">,</span> <span class="n">SplitResult</span><span class="p">,</span> <span class="n">_coerce_args</span><span class="p">,</span> <span class="n">_splitnetloc</span><span class="p">,</span> <span class="n">_splitparams</span><span class="p">,</span>
        <span class="n">scheme_chars</span><span class="p">,</span> <span class="n">uses_params</span><span class="p">,</span>
    <span class="p">)</span>

<span class="c1"># based on RFC 7232, Appendix C</span>
<span class="n">ETAG_MATCH</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;&#39;&#39;</span>
<span class="s1">    \A(      # start of string and capture group</span>
<span class="s1">    (?:W/)?  # optional weak indicator</span>
<span class="s1">    &quot;        # opening quote</span>
<span class="s1">    [^&quot;]*    # any sequence of non-quote characters</span>
<span class="s1">    &quot;        # end quote</span>
<span class="s1">    )\Z      # end of string and capture group</span>
<span class="s1">&#39;&#39;&#39;</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">X</span><span class="p">)</span>

<span class="n">MONTHS</span> <span class="o">=</span> <span class="s1">&#39;jan feb mar apr may jun jul aug sep oct nov dec&#39;</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
<span class="n">__D</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;(?P&lt;day&gt;\d</span><span class="si">{2}</span><span class="s1">)&#39;</span>
<span class="n">__D2</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;(?P&lt;day&gt;[ \d]\d)&#39;</span>
<span class="n">__M</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;(?P&lt;mon&gt;\w</span><span class="si">{3}</span><span class="s1">)&#39;</span>
<span class="n">__Y</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;(?P&lt;year&gt;\d</span><span class="si">{4}</span><span class="s1">)&#39;</span>
<span class="n">__Y2</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;(?P&lt;year&gt;\d</span><span class="si">{2}</span><span class="s1">)&#39;</span>
<span class="n">__T</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;(?P&lt;hour&gt;\d</span><span class="si">{2}</span><span class="s1">):(?P&lt;min&gt;\d</span><span class="si">{2}</span><span class="s1">):(?P&lt;sec&gt;\d</span><span class="si">{2}</span><span class="s1">)&#39;</span>
<span class="n">RFC1123_DATE</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;^\w</span><span class="si">{3}</span><span class="s1">, </span><span class="si">%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1"> GMT$&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">__D</span><span class="p">,</span> <span class="n">__M</span><span class="p">,</span> <span class="n">__Y</span><span class="p">,</span> <span class="n">__T</span><span class="p">))</span>
<span class="n">RFC850_DATE</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;^\w{6,9}, </span><span class="si">%s</span><span class="s1">-</span><span class="si">%s</span><span class="s1">-</span><span class="si">%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1"> GMT$&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">__D</span><span class="p">,</span> <span class="n">__M</span><span class="p">,</span> <span class="n">__Y2</span><span class="p">,</span> <span class="n">__T</span><span class="p">))</span>
<span class="n">ASCTIME_DATE</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;^\w</span><span class="si">{3}</span><span class="s1"> </span><span class="si">%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1">$&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">__M</span><span class="p">,</span> <span class="n">__D2</span><span class="p">,</span> <span class="n">__T</span><span class="p">,</span> <span class="n">__Y</span><span class="p">))</span>

<span class="n">RFC3986_GENDELIMS</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="s2">&quot;:/?#[]@&quot;</span><span class="p">)</span>
<span class="n">RFC3986_SUBDELIMS</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="s2">&quot;!$&amp;&#39;()*+,;=&quot;</span><span class="p">)</span>

<span class="n">FIELDS_MATCH</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s1">&#39;[&amp;;]&#39;</span><span class="p">)</span>


<div class="viewcode-block" id="urlquote"><a class="viewcode-back" href="../../../ref/utils.html#django.utils.http.urlquote">[docs]</a><span class="nd">@keep_lazy_text</span>
<span class="k">def</span> <span class="nf">urlquote</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">safe</span><span class="o">=</span><span class="s1">&#39;/&#39;</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A version of Python&#39;s urllib.quote() function that can operate on unicode</span>
<span class="sd">    strings. The url is first UTF-8 encoded before quoting. The returned string</span>
<span class="sd">    can safely be used as part of an argument to a subsequent iri_to_uri() call</span>
<span class="sd">    without double-quoting occurring.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="n">force_text</span><span class="p">(</span><span class="n">quote</span><span class="p">(</span><span class="n">force_str</span><span class="p">(</span><span class="n">url</span><span class="p">),</span> <span class="n">force_str</span><span class="p">(</span><span class="n">safe</span><span class="p">)))</span></div>


<div class="viewcode-block" id="urlquote_plus"><a class="viewcode-back" href="../../../ref/utils.html#django.utils.http.urlquote_plus">[docs]</a><span class="nd">@keep_lazy_text</span>
<span class="k">def</span> <span class="nf">urlquote_plus</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">safe</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A version of Python&#39;s urllib.quote_plus() function that can operate on</span>
<span class="sd">    unicode strings. The url is first UTF-8 encoded before quoting. The</span>
<span class="sd">    returned string can safely be used as part of an argument to a subsequent</span>
<span class="sd">    iri_to_uri() call without double-quoting occurring.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="n">force_text</span><span class="p">(</span><span class="n">quote_plus</span><span class="p">(</span><span class="n">force_str</span><span class="p">(</span><span class="n">url</span><span class="p">),</span> <span class="n">force_str</span><span class="p">(</span><span class="n">safe</span><span class="p">)))</span></div>


<span class="nd">@keep_lazy_text</span>
<span class="k">def</span> <span class="nf">urlunquote</span><span class="p">(</span><span class="n">quoted_url</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A wrapper for Python&#39;s urllib.unquote() function that can operate on</span>
<span class="sd">    the result of django.utils.http.urlquote().</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="n">force_text</span><span class="p">(</span><span class="n">unquote</span><span class="p">(</span><span class="n">force_str</span><span class="p">(</span><span class="n">quoted_url</span><span class="p">)))</span>


<span class="nd">@keep_lazy_text</span>
<span class="k">def</span> <span class="nf">urlunquote_plus</span><span class="p">(</span><span class="n">quoted_url</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A wrapper for Python&#39;s urllib.unquote_plus() function that can operate on</span>
<span class="sd">    the result of django.utils.http.urlquote_plus().</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="n">force_text</span><span class="p">(</span><span class="n">unquote_plus</span><span class="p">(</span><span class="n">force_str</span><span class="p">(</span><span class="n">quoted_url</span><span class="p">)))</span>


<div class="viewcode-block" id="urlencode"><a class="viewcode-back" href="../../../ref/utils.html#django.utils.http.urlencode">[docs]</a><span class="k">def</span> <span class="nf">urlencode</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">doseq</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A version of Python&#39;s urllib.urlencode() function that can operate on</span>
<span class="sd">    unicode strings. The parameters are first cast to UTF-8 encoded strings and</span>
<span class="sd">    then encoded as per normal.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">MultiValueDict</span><span class="p">):</span>
        <span class="n">query</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">lists</span><span class="p">()</span>
    <span class="k">elif</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="s1">&#39;items&#39;</span><span class="p">):</span>
        <span class="n">query</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">original_urlencode</span><span class="p">(</span>
        <span class="p">[(</span><span class="n">force_str</span><span class="p">(</span><span class="n">k</span><span class="p">),</span>
         <span class="p">[</span><span class="n">force_str</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">v</span><span class="p">]</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">))</span> <span class="k">else</span> <span class="n">force_str</span><span class="p">(</span><span class="n">v</span><span class="p">))</span>
            <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">query</span><span class="p">],</span>
        <span class="n">doseq</span><span class="p">)</span></div>


<div class="viewcode-block" id="cookie_date"><a class="viewcode-back" href="../../../ref/utils.html#django.utils.http.cookie_date">[docs]</a><span class="k">def</span> <span class="nf">cookie_date</span><span class="p">(</span><span class="n">epoch_seconds</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Formats the time to ensure compatibility with Netscape&#39;s cookie standard.</span>

<span class="sd">    Accepts a floating point number expressed in seconds since the epoch, in</span>
<span class="sd">    UTC - such as that outputted by time.time(). If set to None, defaults to</span>
<span class="sd">    the current time.</span>

<span class="sd">    Outputs a string in the format &#39;Wdy, DD-Mon-YYYY HH:MM:SS GMT&#39;.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">rfcdate</span> <span class="o">=</span> <span class="n">formatdate</span><span class="p">(</span><span class="n">epoch_seconds</span><span class="p">)</span>
    <span class="k">return</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">-</span><span class="si">%s</span><span class="s1">-</span><span class="si">%s</span><span class="s1"> GMT&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">rfcdate</span><span class="p">[:</span><span class="mi">7</span><span class="p">],</span> <span class="n">rfcdate</span><span class="p">[</span><span class="mi">8</span><span class="p">:</span><span class="mi">11</span><span class="p">],</span> <span class="n">rfcdate</span><span class="p">[</span><span class="mi">12</span><span class="p">:</span><span class="mi">25</span><span class="p">])</span></div>


<div class="viewcode-block" id="http_date"><a class="viewcode-back" href="../../../ref/utils.html#django.utils.http.http_date">[docs]</a><span class="k">def</span> <span class="nf">http_date</span><span class="p">(</span><span class="n">epoch_seconds</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Formats the time to match the RFC1123 date format as specified by HTTP</span>
<span class="sd">    RFC7231 section 7.1.1.1.</span>

<span class="sd">    Accepts a floating point number expressed in seconds since the epoch, in</span>
<span class="sd">    UTC - such as that outputted by time.time(). If set to None, defaults to</span>
<span class="sd">    the current time.</span>

<span class="sd">    Outputs a string in the format &#39;Wdy, DD Mon YYYY HH:MM:SS GMT&#39;.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="n">formatdate</span><span class="p">(</span><span class="n">epoch_seconds</span><span class="p">,</span> <span class="n">usegmt</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span></div>


<span class="k">def</span> <span class="nf">parse_http_date</span><span class="p">(</span><span class="n">date</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Parses a date format as specified by HTTP RFC7231 section 7.1.1.1.</span>

<span class="sd">    The three formats allowed by the RFC are accepted, even if only the first</span>
<span class="sd">    one is still in widespread use.</span>

<span class="sd">    Returns an integer expressed in seconds since the epoch, in UTC.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="c1"># emails.Util.parsedate does the job for RFC1123 dates; unfortunately</span>
    <span class="c1"># RFC7231 makes it mandatory to support RFC850 dates too. So we roll</span>
    <span class="c1"># our own RFC-compliant parsing.</span>
    <span class="k">for</span> <span class="n">regex</span> <span class="ow">in</span> <span class="n">RFC1123_DATE</span><span class="p">,</span> <span class="n">RFC850_DATE</span><span class="p">,</span> <span class="n">ASCTIME_DATE</span><span class="p">:</span>
        <span class="n">m</span> <span class="o">=</span> <span class="n">regex</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">date</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">m</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">break</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%r</span><span class="s2"> is not in a valid HTTP date format&quot;</span> <span class="o">%</span> <span class="n">date</span><span class="p">)</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">year</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s1">&#39;year&#39;</span><span class="p">))</span>
        <span class="k">if</span> <span class="n">year</span> <span class="o">&lt;</span> <span class="mi">100</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">year</span> <span class="o">&lt;</span> <span class="mi">70</span><span class="p">:</span>
                <span class="n">year</span> <span class="o">+=</span> <span class="mi">2000</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">year</span> <span class="o">+=</span> <span class="mi">1900</span>
        <span class="n">month</span> <span class="o">=</span> <span class="n">MONTHS</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s1">&#39;mon&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span> <span class="o">+</span> <span class="mi">1</span>
        <span class="n">day</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s1">&#39;day&#39;</span><span class="p">))</span>
        <span class="n">hour</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s1">&#39;hour&#39;</span><span class="p">))</span>
        <span class="nb">min</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s1">&#39;min&#39;</span><span class="p">))</span>
        <span class="n">sec</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s1">&#39;sec&#39;</span><span class="p">))</span>
        <span class="n">result</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">(</span><span class="n">year</span><span class="p">,</span> <span class="n">month</span><span class="p">,</span> <span class="n">day</span><span class="p">,</span> <span class="n">hour</span><span class="p">,</span> <span class="nb">min</span><span class="p">,</span> <span class="n">sec</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">calendar</span><span class="o">.</span><span class="n">timegm</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">utctimetuple</span><span class="p">())</span>
    <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
        <span class="n">six</span><span class="o">.</span><span class="n">reraise</span><span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%r</span><span class="s2"> is not a valid date&quot;</span> <span class="o">%</span> <span class="n">date</span><span class="p">),</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">2</span><span class="p">])</span>


<span class="k">def</span> <span class="nf">parse_http_date_safe</span><span class="p">(</span><span class="n">date</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Same as parse_http_date, but returns None if the input is invalid.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">parse_http_date</span><span class="p">(</span><span class="n">date</span><span class="p">)</span>
    <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
        <span class="k">pass</span>


<span class="c1"># Base 36 functions: useful for generating compact URLs</span>

<div class="viewcode-block" id="base36_to_int"><a class="viewcode-back" href="../../../ref/utils.html#django.utils.http.base36_to_int">[docs]</a><span class="k">def</span> <span class="nf">base36_to_int</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Converts a base 36 string to an ``int``. Raises ``ValueError` if the</span>
<span class="sd">    input won&#39;t fit into an int.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="c1"># To prevent overconsumption of server resources, reject any</span>
    <span class="c1"># base36 string that is longer than 13 base36 digits (13 digits</span>
    <span class="c1"># is sufficient to base36-encode any 64-bit integer)</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">13</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Base36 input too large&quot;</span><span class="p">)</span>
    <span class="n">value</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="mi">36</span><span class="p">)</span>
    <span class="c1"># ... then do a final check that the value will fit into an int to avoid</span>
    <span class="c1"># returning a long (#15067). The long type was removed in Python 3.</span>
    <span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY2</span> <span class="ow">and</span> <span class="n">value</span> <span class="o">&gt;</span> <span class="n">sys</span><span class="o">.</span><span class="n">maxint</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Base36 input too large&quot;</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">value</span></div>


<div class="viewcode-block" id="int_to_base36"><a class="viewcode-back" href="../../../ref/utils.html#django.utils.http.int_to_base36">[docs]</a><span class="k">def</span> <span class="nf">int_to_base36</span><span class="p">(</span><span class="n">i</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Converts an integer to a base36 string</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">char_set</span> <span class="o">=</span> <span class="s1">&#39;0123456789abcdefghijklmnopqrstuvwxyz&#39;</span>
    <span class="k">if</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Negative base36 conversion input.&quot;</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY2</span><span class="p">:</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">integer_types</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">&quot;Non-integer base36 conversion input.&quot;</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">i</span> <span class="o">&gt;</span> <span class="n">sys</span><span class="o">.</span><span class="n">maxint</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Base36 conversion input too large.&quot;</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">36</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">char_set</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">b36</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
    <span class="k">while</span> <span class="n">i</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">i</span><span class="p">,</span> <span class="n">n</span> <span class="o">=</span> <span class="nb">divmod</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="mi">36</span><span class="p">)</span>
        <span class="n">b36</span> <span class="o">=</span> <span class="n">char_set</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="o">+</span> <span class="n">b36</span>
    <span class="k">return</span> <span class="n">b36</span></div>


<div class="viewcode-block" id="urlsafe_base64_encode"><a class="viewcode-back" href="../../../ref/utils.html#django.utils.http.urlsafe_base64_encode">[docs]</a><span class="k">def</span> <span class="nf">urlsafe_base64_encode</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Encodes a bytestring in base64 for use in URLs, stripping any trailing</span>
<span class="sd">    equal signs.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="n">base64</span><span class="o">.</span><span class="n">urlsafe_b64encode</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">=&#39;</span><span class="p">)</span></div>


<div class="viewcode-block" id="urlsafe_base64_decode"><a class="viewcode-back" href="../../../ref/utils.html#django.utils.http.urlsafe_base64_decode">[docs]</a><span class="k">def</span> <span class="nf">urlsafe_base64_decode</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Decodes a base64 encoded string, adding back any trailing equal signs that</span>
<span class="sd">    might have been stripped.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">s</span> <span class="o">=</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">base64</span><span class="o">.</span><span class="n">urlsafe_b64decode</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">%</span> <span class="mi">4</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;=&#39;</span><span class="p">))</span>
    <span class="k">except</span> <span class="p">(</span><span class="ne">LookupError</span><span class="p">,</span> <span class="n">BinasciiError</span><span class="p">)</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">e</span><span class="p">)</span></div>


<span class="k">def</span> <span class="nf">parse_etags</span><span class="p">(</span><span class="n">etag_str</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Parse a string of ETags given in an If-None-Match or If-Match header as</span>
<span class="sd">    defined by RFC 7232. Return a list of quoted ETags, or [&#39;*&#39;] if all ETags</span>
<span class="sd">    should be matched.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">etag_str</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;*&#39;</span><span class="p">:</span>
        <span class="k">return</span> <span class="p">[</span><span class="s1">&#39;*&#39;</span><span class="p">]</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="c1"># Parse each ETag individually, and return any that are valid.</span>
        <span class="n">etag_matches</span> <span class="o">=</span> <span class="p">(</span><span class="n">ETAG_MATCH</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">etag</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span> <span class="k">for</span> <span class="n">etag</span> <span class="ow">in</span> <span class="n">etag_str</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">))</span>
        <span class="k">return</span> <span class="p">[</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">etag_matches</span> <span class="k">if</span> <span class="n">match</span><span class="p">]</span>


<span class="k">def</span> <span class="nf">quote_etag</span><span class="p">(</span><span class="n">etag_str</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    If the provided string is already a quoted ETag, return it. Otherwise, wrap</span>
<span class="sd">    the string in quotes, making it a strong ETag.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">ETAG_MATCH</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">etag_str</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">etag_str</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="s1">&#39;&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="n">etag_str</span>


<span class="k">def</span> <span class="nf">is_same_domain</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">pattern</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Return ``True`` if the host is either an exact match or a match</span>
<span class="sd">    to the wildcard pattern.</span>

<span class="sd">    Any pattern beginning with a period matches a domain and all of its</span>
<span class="sd">    subdomains. (e.g. ``.example.com`` matches ``example.com`` and</span>
<span class="sd">    ``foo.example.com``). Anything else is an exact string match.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">pattern</span><span class="p">:</span>
        <span class="k">return</span> <span class="kc">False</span>

    <span class="n">pattern</span> <span class="o">=</span> <span class="n">pattern</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
    <span class="k">return</span> <span class="p">(</span>
        <span class="n">pattern</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;.&#39;</span> <span class="ow">and</span> <span class="p">(</span><span class="n">host</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span> <span class="ow">or</span> <span class="n">host</span> <span class="o">==</span> <span class="n">pattern</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span> <span class="ow">or</span>
        <span class="n">pattern</span> <span class="o">==</span> <span class="n">host</span>
    <span class="p">)</span>


<span class="k">def</span> <span class="nf">is_safe_url</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">host</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">allowed_hosts</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">require_https</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Return ``True`` if the url is a safe redirection (i.e. it doesn&#39;t point to</span>
<span class="sd">    a different host and uses a safe scheme).</span>

<span class="sd">    Always returns ``False`` on an empty url.</span>

<span class="sd">    If ``require_https`` is ``True``, only &#39;https&#39; will be considered a valid</span>
<span class="sd">    scheme, as opposed to &#39;http&#39; and &#39;https&#39; with the default, ``False``.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">url</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">url</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">url</span><span class="p">:</span>
        <span class="k">return</span> <span class="kc">False</span>
    <span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY2</span><span class="p">:</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">url</span> <span class="o">=</span> <span class="n">force_text</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
        <span class="k">except</span> <span class="ne">UnicodeDecodeError</span><span class="p">:</span>
            <span class="k">return</span> <span class="kc">False</span>
    <span class="k">if</span> <span class="n">allowed_hosts</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">allowed_hosts</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
    <span class="k">if</span> <span class="n">host</span><span class="p">:</span>
        <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span>
            <span class="s2">&quot;The host argument is deprecated, use allowed_hosts instead.&quot;</span><span class="p">,</span>
            <span class="n">RemovedInDjango21Warning</span><span class="p">,</span>
            <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span>
        <span class="p">)</span>
        <span class="c1"># Avoid mutating the passed in allowed_hosts.</span>
        <span class="n">allowed_hosts</span> <span class="o">=</span> <span class="n">allowed_hosts</span> <span class="o">|</span> <span class="p">{</span><span class="n">host</span><span class="p">}</span>
    <span class="c1"># Chrome treats \ completely as / in paths but it could be part of some</span>
    <span class="c1"># basic auth credentials so we need to check both URLs.</span>
    <span class="k">return</span> <span class="p">(</span><span class="n">_is_safe_url</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">allowed_hosts</span><span class="p">,</span> <span class="n">require_https</span><span class="o">=</span><span class="n">require_https</span><span class="p">)</span> <span class="ow">and</span>
            <span class="n">_is_safe_url</span><span class="p">(</span><span class="n">url</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">),</span> <span class="n">allowed_hosts</span><span class="p">,</span> <span class="n">require_https</span><span class="o">=</span><span class="n">require_https</span><span class="p">))</span>


<span class="c1"># Copied from urllib.parse.urlparse() but uses fixed urlsplit() function.</span>
<span class="k">def</span> <span class="nf">_urlparse</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">scheme</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">allow_fragments</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Parse a URL into 6 components:</span>
<span class="sd">    &lt;scheme&gt;://&lt;netloc&gt;/&lt;path&gt;;&lt;params&gt;?&lt;query&gt;#&lt;fragment&gt;</span>
<span class="sd">    Return a 6-tuple: (scheme, netloc, path, params, query, fragment).</span>
<span class="sd">    Note that we don&#39;t break the components up in smaller bits</span>
<span class="sd">    (e.g. netloc is a single string) and we don&#39;t expand % escapes.&quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">_coerce_args</span><span class="p">:</span>
        <span class="n">url</span><span class="p">,</span> <span class="n">scheme</span><span class="p">,</span> <span class="n">_coerce_result</span> <span class="o">=</span> <span class="n">_coerce_args</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">scheme</span><span class="p">)</span>
    <span class="n">splitresult</span> <span class="o">=</span> <span class="n">_urlsplit</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">scheme</span><span class="p">,</span> <span class="n">allow_fragments</span><span class="p">)</span>
    <span class="n">scheme</span><span class="p">,</span> <span class="n">netloc</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">query</span><span class="p">,</span> <span class="n">fragment</span> <span class="o">=</span> <span class="n">splitresult</span>
    <span class="k">if</span> <span class="n">scheme</span> <span class="ow">in</span> <span class="n">uses_params</span> <span class="ow">and</span> <span class="s1">&#39;;&#39;</span> <span class="ow">in</span> <span class="n">url</span><span class="p">:</span>
        <span class="n">url</span><span class="p">,</span> <span class="n">params</span> <span class="o">=</span> <span class="n">_splitparams</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">params</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
    <span class="n">result</span> <span class="o">=</span> <span class="n">ParseResult</span><span class="p">(</span><span class="n">scheme</span><span class="p">,</span> <span class="n">netloc</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">query</span><span class="p">,</span> <span class="n">fragment</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">_coerce_result</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="k">if</span> <span class="n">_coerce_args</span> <span class="k">else</span> <span class="n">result</span>


<span class="c1"># Copied from urllib.parse.urlsplit() with</span>
<span class="c1"># https://github.com/python/cpython/pull/661 applied.</span>
<span class="k">def</span> <span class="nf">_urlsplit</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">scheme</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">allow_fragments</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Parse a URL into 5 components:</span>
<span class="sd">    &lt;scheme&gt;://&lt;netloc&gt;/&lt;path&gt;?&lt;query&gt;#&lt;fragment&gt;</span>
<span class="sd">    Return a 5-tuple: (scheme, netloc, path, query, fragment).</span>
<span class="sd">    Note that we don&#39;t break the components up in smaller bits</span>
<span class="sd">    (e.g. netloc is a single string) and we don&#39;t expand % escapes.&quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">_coerce_args</span><span class="p">:</span>
        <span class="n">url</span><span class="p">,</span> <span class="n">scheme</span><span class="p">,</span> <span class="n">_coerce_result</span> <span class="o">=</span> <span class="n">_coerce_args</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">scheme</span><span class="p">)</span>
    <span class="n">allow_fragments</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span><span class="n">allow_fragments</span><span class="p">)</span>
    <span class="n">netloc</span> <span class="o">=</span> <span class="n">query</span> <span class="o">=</span> <span class="n">fragment</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
    <span class="n">i</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;:&#39;</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">i</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">url</span><span class="p">[:</span><span class="n">i</span><span class="p">]:</span>
            <span class="k">if</span> <span class="n">c</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">scheme_chars</span><span class="p">:</span>
                <span class="k">break</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">scheme</span><span class="p">,</span> <span class="n">url</span> <span class="o">=</span> <span class="n">url</span><span class="p">[:</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="n">url</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">:]</span>

    <span class="k">if</span> <span class="n">url</span><span class="p">[:</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;//&#39;</span><span class="p">:</span>
        <span class="n">netloc</span><span class="p">,</span> <span class="n">url</span> <span class="o">=</span> <span class="n">_splitnetloc</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
        <span class="k">if</span> <span class="p">((</span><span class="s1">&#39;[&#39;</span> <span class="ow">in</span> <span class="n">netloc</span> <span class="ow">and</span> <span class="s1">&#39;]&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">netloc</span><span class="p">)</span> <span class="ow">or</span>
                <span class="p">(</span><span class="s1">&#39;]&#39;</span> <span class="ow">in</span> <span class="n">netloc</span> <span class="ow">and</span> <span class="s1">&#39;[&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">netloc</span><span class="p">)):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Invalid IPv6 URL&quot;</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">allow_fragments</span> <span class="ow">and</span> <span class="s1">&#39;#&#39;</span> <span class="ow">in</span> <span class="n">url</span><span class="p">:</span>
        <span class="n">url</span><span class="p">,</span> <span class="n">fragment</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;#&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
    <span class="k">if</span> <span class="s1">&#39;?&#39;</span> <span class="ow">in</span> <span class="n">url</span><span class="p">:</span>
        <span class="n">url</span><span class="p">,</span> <span class="n">query</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;?&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
    <span class="n">v</span> <span class="o">=</span> <span class="n">SplitResult</span><span class="p">(</span><span class="n">scheme</span><span class="p">,</span> <span class="n">netloc</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">query</span><span class="p">,</span> <span class="n">fragment</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">_coerce_result</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">if</span> <span class="n">_coerce_args</span> <span class="k">else</span> <span class="n">v</span>


<span class="k">def</span> <span class="nf">_is_safe_url</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">allowed_hosts</span><span class="p">,</span> <span class="n">require_https</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
    <span class="c1"># Chrome considers any URL with more than two slashes to be absolute, but</span>
    <span class="c1"># urlparse is not so flexible. Treat any url with three slashes as unsafe.</span>
    <span class="k">if</span> <span class="n">url</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;///&#39;</span><span class="p">):</span>
        <span class="k">return</span> <span class="kc">False</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">url_info</span> <span class="o">=</span> <span class="n">_urlparse</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
    <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>  <span class="c1"># e.g. invalid IPv6 addresses</span>
        <span class="k">return</span> <span class="kc">False</span>
    <span class="c1"># Forbid URLs like http:///example.com - with a scheme, but without a hostname.</span>
    <span class="c1"># In that URL, example.com is not the hostname but, a path component. However,</span>
    <span class="c1"># Chrome will still consider example.com to be the hostname, so we must not</span>
    <span class="c1"># allow this syntax.</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">url_info</span><span class="o">.</span><span class="n">netloc</span> <span class="ow">and</span> <span class="n">url_info</span><span class="o">.</span><span class="n">scheme</span><span class="p">:</span>
        <span class="k">return</span> <span class="kc">False</span>
    <span class="c1"># Forbid URLs that start with control characters. Some browsers (like</span>
    <span class="c1"># Chrome) ignore quite a few control characters at the start of a</span>
    <span class="c1"># URL and might consider the URL as scheme relative.</span>
    <span class="k">if</span> <span class="n">unicodedata</span><span class="o">.</span><span class="n">category</span><span class="p">(</span><span class="n">url</span><span class="p">[</span><span class="mi">0</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;C&#39;</span><span class="p">:</span>
        <span class="k">return</span> <span class="kc">False</span>
    <span class="n">scheme</span> <span class="o">=</span> <span class="n">url_info</span><span class="o">.</span><span class="n">scheme</span>
    <span class="c1"># Consider URLs without a scheme (e.g. //example.com/p) to be http.</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">url_info</span><span class="o">.</span><span class="n">scheme</span> <span class="ow">and</span> <span class="n">url_info</span><span class="o">.</span><span class="n">netloc</span><span class="p">:</span>
        <span class="n">scheme</span> <span class="o">=</span> <span class="s1">&#39;http&#39;</span>
    <span class="n">valid_schemes</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;https&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="n">require_https</span> <span class="k">else</span> <span class="p">[</span><span class="s1">&#39;http&#39;</span><span class="p">,</span> <span class="s1">&#39;https&#39;</span><span class="p">]</span>
    <span class="k">return</span> <span class="p">((</span><span class="ow">not</span> <span class="n">url_info</span><span class="o">.</span><span class="n">netloc</span> <span class="ow">or</span> <span class="n">url_info</span><span class="o">.</span><span class="n">netloc</span> <span class="ow">in</span> <span class="n">allowed_hosts</span><span class="p">)</span> <span class="ow">and</span>
            <span class="p">(</span><span class="ow">not</span> <span class="n">scheme</span> <span class="ow">or</span> <span class="n">scheme</span> <span class="ow">in</span> <span class="n">valid_schemes</span><span class="p">))</span>


<span class="k">def</span> <span class="nf">limited_parse_qsl</span><span class="p">(</span><span class="n">qs</span><span class="p">,</span> <span class="n">keep_blank_values</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">,</span>
                      <span class="n">errors</span><span class="o">=</span><span class="s1">&#39;replace&#39;</span><span class="p">,</span> <span class="n">fields_limit</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Return a list of key/value tuples parsed from query string.</span>

<span class="sd">    Copied from urlparse with an additional &quot;fields_limit&quot; argument.</span>
<span class="sd">    Copyright (C) 2013 Python Software Foundation (see LICENSE.python).</span>

<span class="sd">    Arguments:</span>

<span class="sd">    qs: percent-encoded query string to be parsed</span>

<span class="sd">    keep_blank_values: flag indicating whether blank values in</span>
<span class="sd">        percent-encoded queries should be treated as blank strings. A</span>
<span class="sd">        true value indicates that blanks should be retained as blank</span>
<span class="sd">        strings. The default false value indicates that blank values</span>
<span class="sd">        are to be ignored and treated as if they were  not included.</span>

<span class="sd">    encoding and errors: specify how to decode percent-encoded sequences</span>
<span class="sd">        into Unicode characters, as accepted by the bytes.decode() method.</span>

<span class="sd">    fields_limit: maximum number of fields parsed or an exception</span>
<span class="sd">        is raised. None means no limit and is the default.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">fields_limit</span><span class="p">:</span>
        <span class="n">pairs</span> <span class="o">=</span> <span class="n">FIELDS_MATCH</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">qs</span><span class="p">,</span> <span class="n">fields_limit</span><span class="p">)</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">pairs</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">fields_limit</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">TooManyFieldsSent</span><span class="p">(</span>
                <span class="s1">&#39;The number of GET/POST parameters exceeded &#39;</span>
                <span class="s1">&#39;settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.&#39;</span>
            <span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">pairs</span> <span class="o">=</span> <span class="n">FIELDS_MATCH</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">qs</span><span class="p">)</span>
    <span class="n">r</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">name_value</span> <span class="ow">in</span> <span class="n">pairs</span><span class="p">:</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">name_value</span><span class="p">:</span>
            <span class="k">continue</span>
        <span class="n">nv</span> <span class="o">=</span> <span class="n">name_value</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="s1">&#39;=&#39;</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">nv</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
            <span class="c1"># Handle case of a control-name with no equal sign</span>
            <span class="k">if</span> <span class="n">keep_blank_values</span><span class="p">:</span>
                <span class="n">nv</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">continue</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">nv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="ow">or</span> <span class="n">keep_blank_values</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">six</span><span class="o">.</span><span class="n">PY3</span><span class="p">:</span>
                <span class="n">name</span> <span class="o">=</span> <span class="n">nv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="s1">&#39; &#39;</span><span class="p">)</span>
                <span class="n">name</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">encoding</span><span class="p">,</span> <span class="n">errors</span><span class="o">=</span><span class="n">errors</span><span class="p">)</span>
                <span class="n">value</span> <span class="o">=</span> <span class="n">nv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="s1">&#39; &#39;</span><span class="p">)</span>
                <span class="n">value</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">encoding</span><span class="p">,</span> <span class="n">errors</span><span class="o">=</span><span class="n">errors</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">name</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">nv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">))</span>
                <span class="n">value</span> <span class="o">=</span> <span class="n">unquote</span><span class="p">(</span><span class="n">nv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39; &#39;</span><span class="p">))</span>
            <span class="n">r</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">))</span>
    <span class="k">return</span> <span class="n">r</span>


<span class="k">def</span> <span class="nf">escape_leading_slashes</span><span class="p">(</span><span class="n">url</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    If redirecting to an absolute path (two leading slashes), a slash must be</span>
<span class="sd">    escaped to prevent browsers from handling the path as schemaless and</span>
<span class="sd">    redirecting to another host.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">url</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;//&#39;</span><span class="p">):</span>
        <span class="n">url</span> <span class="o">=</span> <span class="s1">&#39;/</span><span class="si">%2F{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">url</span><span class="p">[</span><span class="mi">2</span><span class="p">:])</span>
    <span class="k">return</span> <span class="n">url</span>
</pre></div>

          </div>
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">Jun 03, 2019</p>
          </div>
        
      
    </div>

    <div id="ft">
      <div class="nav">
    <a href="../../index.html" title="Module code" accesskey="U">up</a></div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>